#pragma once
//============================================================================
// Copyright (C) 2010-2013 Brett R. Jones
// All Rights Reserved
//
// You may redistribute and/or modify for non commercial and commercial uses
// provided this copyright notice remains in place and is not modified
//
// This code is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//
// brettjones1900@gmail.com
// http://www.p2panarchy.com
//============================================================================

//=== color definitions ===//
#define SCOLOR_WHITE      video::SColor(255,255,255,255)
#define SCOLOR_LIGHTGRAY  video::SColor(255,230,230,230)
#define SCOLOR_MIDGRAY    video::SColor(255,128,128,128)
#define SCOLOR_DARKGRAY   video::SColor(255,64,64,64)
#define SCOLOR_BLACK      video::SColor(255,0,0,0)

enum ECubeSide
{
	eCubeSideLeft		= 0,
	eCubeSideRight		= 1,
	eCubeSideFront		= 2,
	eCubeSideBack		= 3,
	eCubeSideTop		= 4,
	eCubeSideBottom		= 5,
	eMaxCubeSide
};


// forward declare
class IrrPhysBase;
class EntBase;

class VxIrrBase
{
public:
	//=== vars ===//
	//=== time vars ===//
	U32									m_u32LastMs;			// last time in milliseconds
	U32									m_u32MsElapsedThisFrame;// milliseconds elapsed this frame

	//=== managers/drivers ===//
	irr::IrrlichtDevice*				m_poDevice;			// irrlicht device
	irr::video::IVideoDriver*			m_poDriver;			// irrlicht video driver
	irr::scene::ISceneManager*			m_poSceneMgr;		// irrlicht scene manager
	irr::gui::IGUIEnvironment*			m_poGui;			// irrlicht gui driver
	irr::scene::ISceneCollisionManager* m_poCollideMgr;
	irr::ITimer *						m_poTimer;			// irrlicht timer
	irr::gui::IGUIFont*					m_poDefaultFont;	// default font
	BOOL								m_bIsMainGameManager; // if true this is main irrlicht device and not a seperate viewport etc

	//=== camera vars ===//
	CameraBase *						m_poCam;			// camera
	int									m_iScnSizeX;		// screen width
	int									m_iScnSizeY;		// screen height
	//=== intersect vars ===//
	irr::core::vector3df				m_v3fZeroOrigin; 	// 3d vector with all zeros
	irr::core::vector3df				m_v3fNormalXY; 		// 3d normal for x-y plane
	irr::core::plane3df					m_oPlaneXY;			// x-y plane used for mouse intersect x-y plane
	irr::core::vector3df				m_v3fNormalXZ; 		// 3d normal for x-z plane
	irr::core::plane3df					m_oPlaneXZ;			// x-z plane used for mouse intersect x-y plane

	//=== physics vars ===//
	IrrPhysBase *						m_poPhysBase;		// pointer to physics class

	//=== level and game state vars ===//
	int									m_iGameInstance;		// how many games played
	int									m_iGameLevel;			// current game level
	int									m_iGameScore;			// game score
	int									m_iGameBonusPoints;		// bonus poings
	int									m_iGameTime;			// time in seconds to complete the level
	U32									m_u32GameTimeMs;		// time in milli seconds to complete the level
	int									m_iGameHits;			// how many times impacted earth land
	int									m_iGameMisses;			// how many times impacted earth sea
	int									m_iGamePercentComplete;	// percentage of game completed
	BOOL								m_bNeedProgressUpdate;	// need progress update
	
	//=== hit points message etc ===//
	irr::core::array<TimedMessage *>	m_apoTimedMessages;		// timed in game messages

	#ifdef WIN_PLATFORM
		HWND							m_hWnd;
	#endif // WIN_PLATFORM

	//------------------------------------------------------------------------
	//=== methods ===//
	//------------------------------------------------------------------------

	//=== constructor ===//
	VxIrrBase();
	//=== destructor ===//
	virtual ~VxIrrBase();

	//! initialize
	#ifdef WIN_PLATFORM
		virtual RCODE IrrBaseStartup( HWND hWnd, int iScnSizeX, int iScnSizeY );
	#else
		virtual RCODE IrrBaseStartup( int iScnSizeX, int iScnSizeY );
	#endif

	//! prepare for destruction
	virtual void IrrBaseShutdown( void );

	//! video suface was lost.. need complete restart of irrlich
	virtual RCODE IrrBaseRestart( void );
	
	//! irrlicht was restarted.. let derived class do any required restart actions 
	virtual RCODE OnIrrlichtRestart( void ){return 0;};

	//! Set physics engine
	virtual void SetGamePhys(IrrPhysBase * poPhysBase ){ m_poPhysBase = poPhysBase;};

	//! override
	//! called if collision occures
	virtual void HandleCollision(EntBase * poEnt1, EntBase * poEnt2 ){};



	//! render a frame
	virtual void RenderFrame( U32 u32TimeMs );

	//============================================================================
	//=== skybox functions ===//
	//============================================================================
	//! set skybox
	virtual RCODE SetSkyBox(const irr::c8 * pSkyLeftFileName,	// file name of skybox left texture
							const irr::c8 * pSkyRightFileName,	// file name of skybox right texture
							const irr::c8 * pSkyFrontFileName,	// file name of skybox front texture
							const irr::c8 * pSkyBackFileName,	// file name of skybox Back texture
							const irr::c8 * pSkyUpFileName,		// file name of skybox up texture
							const irr::c8 * pSkyDownFileName );	// file name of skybox down texture

	//============================================================================
	//=== helper utility functions ===//
	//============================================================================
	//! unproject screen coordinates into a world position.. return 0 if no error
	RCODE 	ScreenToWorld( int screenx, int screeny, int screenz, irr::core::vector3df & v3fRetPos );
	//! project world position onto screen coordinates .. return zero if within screen coords
	void 	WorldToScreen(	irr::core::vector3df v3fObjPos,
							irr::core::position2d<irr::s32> & v2dRetScreenPos );
	//! calculate where line from mouse pos into world intersects the x-y plane
	//! return true if intersect occurs else return false
	bool 	GetXYPlaneIntersect( int iMousePosX, int iMousePosY, irr::core::vector3df& v3fRetPos );
	//! calculate where line from mouse pos into world intersects the x-z plane
	//! return true if intersect occurs else return false
	bool 	GetXZPlaneIntersect( int iMousePosX, int iMousePosY, irr::core::vector3df& v3fRetPos );

	//! take snapshot and save to jpg file
	void	CreateScreenshot( char * pFilePathAndName );

	//============================================================================
	//! add smoke style trail to scene node
	virtual irr::scene::IParticleSystemSceneNode *  AddCometTrailParticleSystem(	irr::scene::ISceneNode * poSceneNode, const char * pTextureFile, float f32Scale );

	//! show message on screen for the given time
	virtual void ShowTimedMessage( const irr::core::vector3df& v3fPos, const char * pMsg, int iSeconds, irr::u32 u32Color = 0xffffffff );
	//! clear out any timed message
	virtual void ClearTimedMessages( void );


	//! called once per second during game play
	virtual void GamePlayOncePerSecond( void );


	//============================================================================
	//! get rectagle centered about a point
	irr::core::rect<irr::s32> GetCenteredRect( int iPosX, int iPosY, int iWidth, int iHeight );

};
